package com.heo.util;

import javax.net.ssl.SSLContext;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

public class HttpHelper
{
  // Increase max total connection to 200
  private static PoolingHttpClientConnectionManager cm = null;
  private static Logger log = Logger.getLogger(HttpHelper.class);

  /**
   * 向服务端请求超时时间设置(单位:毫秒)
   */
  private static int SERVER_REQUEST_TIME_OUT = 5000;

  /**
   * 服务端响应超时时间设置(单位:毫秒)
   */
  private static int SERVER_RESPONSE_TIME_OUT = 5000;

  private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SERVER_REQUEST_TIME_OUT).setConnectTimeout(SERVER_RESPONSE_TIME_OUT).build();

  static
  {
    cm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(2000);// 设置http连接池大小
    cm.setDefaultMaxPerRoute(200);// 单路由最大大小,设置每个路由默认连接数
  }

  public HttpHelper()
  {
    // Increase default max connection per route to 20
    // cm.setMaxTotal(SysConfig.getInstance().getHttpMaxTotal());
    // Increase max connections for localhost:80 to 50
    // cm.setDefaultMaxPerRoute(SysConfig.getInstance().getHttpDefaultMaxPerRoute());
    // HttpHost localhost = new HttpHost("locahost", 80);
    // cm.setMaxPerRoute(new HttpRoute(localhost), 50);
  }

  public static String sendHttpGet(String url)
  {
    return sendHttpGet(url, "UTF-8");
  }

  public static String sendHttpGet(String url, String charsetName)
  {
    String xx = new String();
    HttpGet httpGet = null;
    CloseableHttpResponse response = null;
    CloseableHttpClient httpclient = null;
    try
    {
      // 如果循环完毕还没有找到，那么就发送请求去管理系统中找
      httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).setConnectionManagerShared(true).build();
      log.debug("[httpclient]发送http get请求，URL：" + url);
      httpGet = new HttpGet(url);
      httpGet.addHeader("Connection", "close");
      response = httpclient.execute(httpGet);
      String content = EntityUtils.toString(response.getEntity(), charsetName);
      EntityUtils.consume(response.getEntity());// 关闭数据流
      if (response.getStatusLine().getStatusCode() == 200)
      {
        log.debug("[httpclient]http get请求发送成功，返回内容：" + content);
        return content;
      }
      else
      {
        log.debug("[httpclient]http get请求发送失败，返回代码：" + response.getStatusLine().getStatusCode() + "，返回内容：" + content);
        return null;
      }
    }
    catch (Exception e)
    {
      log.error(e.getMessage(), e);
      return null;
    }
    finally
    {
      if (httpGet != null)
      {
        try
        {
          httpGet.releaseConnection();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (response != null)
      {
        try
        {
          response.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (httpclient != null)
      {
        try
        {
          httpclient.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
    }
  }

  public static String sendHttpsGet(String url) throws Exception
  {
    return sendHttpsGet(url, "UTF-8");
  }

  public static String sendHttpsGet(String url, String charsetName) throws Exception
  {
    CloseableHttpClient httpclient = null;
    CloseableHttpResponse response = null;
    HttpGet httpget = null;
    try
    {
      // Trust own CA and all self-signed certs
      SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
      // Allow TLSv1 protocol only
      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
      httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).setConnectionManagerShared(true).setSSLSocketFactory(sslsf).build();
      log.debug("[httpclient]发送https get请求，URL：" + url);
      httpget = new HttpGet(url);
      httpget.addHeader("Connection", "close");
      response = httpclient.execute(httpget);

      String content = EntityUtils.toString(response.getEntity(), charsetName);
      EntityUtils.consume(response.getEntity());// 关闭数据流
      if (response.getStatusLine().getStatusCode() == 200)
      {
        log.debug("[httpclient]https get请求发送成功，返回内容：" + content);
        return content;
      }
      else
      {
        log.debug("[httpclient]https get请求发送失败，返回代码：" + response.getStatusLine().getStatusCode() + "，返回内容：" + content);
        return null;
      }
    }
    catch (Exception ex)
    {
      log.error(ex.getMessage(), ex);
    }
    finally
    {
      if (httpget != null)
      {
        try
        {
          httpget.releaseConnection();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (response != null)
      {
        try
        {
          response.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (httpclient != null)
      {
        try
        {
          httpclient.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
    }
    return null;
  }

  public static String sendHttpPost(String url, String content)
  {
    return sendHttpPost(url, content, "UTF-8");
  }

  public static String sendHttpPost(String url, String postBody, String charsetName)
  {
    CloseableHttpClient httpclient = null;
    CloseableHttpResponse response = null;
    HttpPost httppost = null;
    try
    {
      httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).setConnectionManagerShared(true).build();
      log.debug("[httpclient]发送http post请求，URL：" + url + "，content：" + postBody);
      httppost = new HttpPost(url);
      httppost.addHeader("Connection", "close");
      httppost.setEntity(new StringEntity(postBody, "UTF-8"));
      response = httpclient.execute(httppost);
      String content = EntityUtils.toString(response.getEntity(), charsetName);
      EntityUtils.consume(response.getEntity());// 关闭数据流
      if (response.getStatusLine().getStatusCode() == 200)
      {
        log.debug("[httpclient]http post请求发送成功，返回内容：" + content);
        return content;
      }
      else
      {
        log.debug("[httpclient]http post请求发送失败，返回代码：" + response.getStatusLine().getStatusCode() + "，返回内容：" + content);
        return null;
      }
    }
    catch (Exception ex)
    {
      log.error(ex.getMessage(), ex);
    }
    finally
    {
      if (httppost != null)
      {
        try
        {
          httppost.releaseConnection();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (response != null)
      {
        try
        {
          response.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (httpclient != null)
      {
        try
        {
          httpclient.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
    }
    return null;
  }

  public static String sendHttpsPost(String url, String postBody)
  {
    return sendHttpsPost(url, postBody, "UTF-8");
  }

  public static String sendHttpsPost(String url, String postBody, String charsetName)
  {
    CloseableHttpClient httpclient = null;
    CloseableHttpResponse response = null;
    HttpPost httppost = null;
    try
    {
      // Trust own CA and all self-signed certs
      SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
      // Allow TLSv1 protocol only
      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
      httpclient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).setConnectionManagerShared(true).setSSLSocketFactory(sslsf).build();
      log.debug("[httpclient]发送https post请求，URL：" + url);
      httppost = new HttpPost(url);
      httppost.addHeader("Connection", "close");
      httppost.setEntity(new StringEntity(postBody, "UTF-8"));
      response = httpclient.execute(httppost);
      String content = EntityUtils.toString(response.getEntity(), charsetName);
      EntityUtils.consume(response.getEntity());// 关闭数据流
      if (response.getStatusLine().getStatusCode() == 200)
      {
        log.debug("[httpclient]https post请求发送成功，返回内容：" + content);
        return content;
      }
      else
      {
        log.debug("[httpclient]https post请求发送失败，返回代码：" + response.getStatusLine().getStatusCode() + "，返回内容：" + content);
        return null;
      }
    }
    catch (Exception ex)
    {
      log.error(ex.getMessage(), ex);
    }
    finally
    {
      if (httppost != null)
      {
        try
        {
          httppost.releaseConnection();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (response != null)
      {
        try
        {
          response.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
      if (httpclient != null)
      {
        try
        {
          httpclient.close();
        }
        catch (Exception e2)
        {
          log.error(e2.getMessage(), e2);
        }
      }
    }
    return null;
  }

  public static void main(String[] args)
  {
    try
    {
      String xx = "";
      System.out.println(sendHttpsPost("https://www.baidu.com/", xx));
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

}
